package Main
{
	import flash.net.FileReference;
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.controls.Alert;
	import mx.controls.Text;
	import mx.events.CloseEvent;
	
	import singleton.ATLSingleton;
	import singleton.GUIController;
	import singleton.Session;

	public class UploadHandler {
		
		private static var fileKeepers:FileReferenceHandlers = FileReferenceHandlers.getInstance();;
		private static var controller:GUIController = GUIController.getInstance();
		private static var atl:ATLSingleton;
		private static var metamodelsID:ArrayList = new ArrayList();
		private static var session:Session = Session.getInstance();
		private static var contentHold:ArrayList = new ArrayList();
		
		public function UploadHandler() {}
		
		/**
		 * Initiates this state
		 * */
		public static function initState():void {
			controller.changeState(GUIController.UPLOAD);
		}
		
		
		public static function toggleUploadButton(state:Boolean): void {
			controller.getButton(GUIController.UPLOAD).mouseEnabled = state;
			if (state == true) {
				controller.getButton(GUIController.UPLOAD).setStyle("chromeColor", 0xe3dddd);
				controller.getButton(GUIController.UPLOAD).setStyle("color", 0x000000);
			} else {
				controller.getButton(GUIController.UPLOAD).setStyle("color", 0xc4c4c4);
				controller.getButton(GUIController.UPLOAD).setStyle("chromeColor", 0xafafaf);
			}
		}
		
		public static function toggleSelectAtlButton(state:Boolean): void {
			controller.getButton(GUIController.ATL_FILE).mouseEnabled = state;
			if (state == true) {
				controller.getButton(GUIController.ATL_FILE).setStyle("chromeColor", 0xe3dddd);
				controller.getButton(GUIController.ATL_FILE).setStyle("color", 0x000000);
				controller.getTextInput(GUIController.ATL_FILE).setStyle("borderColor", 0xb01303);
			} else {
				controller.getButton(GUIController.ATL_FILE).setStyle("color", 0xc4c4c4);
				controller.getButton(GUIController.ATL_FILE).setStyle("chromeColor", 0xafafaf);
			}
		}
		
		/**
		 * Expands the panel and asks the user for metamodels
		 * */
		public static function askForMetamodels():void {
			expandAction();
			controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), "#4");
			controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), "#6");
			Alert.show("ATL File uploaded. Now select the required metamodels.", "Info");
			toggleUploadButton(false);
			toggleSelectAtlButton(false);
			controller.getImage(GUIController.ATL_FILE).setVisible(true);
			controller.getTextInput(GUIController.ATL_FILE).setStyle("borderColor", 0x2813c8);
		}
		
		/**
		 * Expand the content panel and shows more options
		 * */
		public static function expandAction(): void {
			controller.getTextInput(GUIController.SRC_METAMODEL).setStyle("color", 0x000000);
			controller.getTextInput(GUIController.TRGT_METAMODEL).setStyle("color", 0x000000);
			controller.getProgressBar(GUIController.UPLOAD).x = 130;
			controller.getAction(GUIController.UPLOAD).play();
			
			
		}
		
		/**
		 * Reverts the expansion of the panel
		 * */
		public static function undoExpansion(): void {
			controller.getProgressBar(GUIController.UPLOAD).setVisible(false);
			controller.getProgressBar(GUIController.UPLOAD).x = 36;
			controller.getAction(GUIController.UPLOAD).play(null, true);
			controller.getImage(GUIController.SRC_METAMODEL).setVisible(false);
			controller.getImage(GUIController.TRGT_METAMODEL).setVisible(false);
			toggleUploadButton(false);
			toggleSelectAtlButton(true);
		}
		
		/**
		 * Resets a text field. Type can be 'atl', 'source metamodel' or 'target metamodel' 
		 * */
		public static function resetField(type:String): void {
			var resetText:String = "";
			switch (type) {
				case GUIController.ATL_FILE:
					resetText = "ATL Transformation";
					break;
				case GUIController.SRC_METAMODEL:
					resetText = "Source Metamodel";
					break;
				case GUIController.TRGT_METAMODEL:
					resetText = "Target Metamodel";
					break;
				default:
					return;
			}
			controller.getTextInput(type).text = resetText;
			
		}
		
		public static function selectAtlFile():void {
			
			fileKeepers.browserATLFile.browse(Util.getAtlArray());
			
		}
		
		public static function selectSourceMetamodel():void {
			try {
				
				if (fileKeepers.browserATLFile.data == null) {
					throw new Error();
				}
				
			} catch (err:Error) {
				
				Alert.show("You must select a transformation first!!", "Error");
				return;
			}
			
			fileKeepers.browserSrcMM.browse(Util.getMetamodelArray());
		}
		
		
		/**
		 * Sets the currently used atl ID
		 * */
		public static function setATLFileID(id:String):void {
			atl = ATLSingleton.getInstance();
			atl.setCurrentId(id);
		}
		
		/**
		 * Sets the currently used metamodel IDs
		 * */
		public static function setMetamodelID(id:String):void {
			//Verificar o tipo de metamodelo. Guardar o ID dos metamodelos de entrada
			metamodelsID.addItem(id);
			if (metamodelsID.length == 1) {
				controller.restartTimer();
				var targetMetamodelName:String = controller.getTextInput(GUIController.TRGT_METAMODEL).text.replace(".ecore", "");
				controller.getWebService().uploadMetamodel(session.getId(), fileKeepers.browserTrgtMM.data, targetMetamodelName, 0);
			} else {
				UploadHandler.undoExpansion();
				toggleProgressBar(false);
				Alert.show("ATL Transformation " + controller.getTextInput(GUIController.ATL_FILE).text.replace(".atl", "") + " uploaded\nWould you like to execute it? If not, you can keep uploading more transformations right now.", "Success!", (Alert.YES | Alert.NO), null, goToExecutionHandler);
				
			}
		}
		
		public static function getMetamodelId():ArrayList {
			return metamodelsID;
		}
		
		
		public static function selectTargetMetamodel():void {
			try {
				
				if (fileKeepers.browserATLFile.data == null) {
					throw new Error();
				}
			} catch (err:Error) {
				Alert.show("You must select a transformation first!", "Error");
				return;
			}
			
			fileKeepers.browserTrgtMM.browse(Util.getMetamodelArray());
		}
		
		/**
		 * Begins the upload of the files selected by the user
		 * */
		public static function uploadFiles():void	{
			metamodelsID.removeAll();
			controller.getProgressBar(GUIController.UPLOAD).setVisible(true);
			controller.getProgressBar(GUIController.UPLOAD).setProgress(90,100);
			try {
				if (controller.getBorderContainer(GUIController.UPLOAD).width < 200) {
					
					controller.getWebService().uploadATLFile(session.getId(), fileKeepers.browserATLFile.data);
					
				} else {
					//var sourceMetamodelName:String = controller.getTextInput(GUIController.SRC_METAMODEL).text.replace(".ecore", "");
					//controller.getWebService().uploadMetamodel(session.getId(), fileKeepers.browserSrcMM.data, sourceMetamodelName, 0);
					// TODO adicionar botao para saber se o usuario quer persistir o metamodelo
					var file:FileReference;
					var selectedFileArray:Array = fileKeepers.browserSrcMM.fileList;
					var content:String = "";
					var sourceMetamodelName:String;
					
					for (var i:uint = 0; i < selectedFileArray.length; i++)	{
						file = FileReference(selectedFileArray[i]);
						sourceMetamodelName = file.name.replace(".ecore", "");
						controller.getWebService().uploadMetamodel(session.getId(), file.data, sourceMetamodelName, 0);
					}
					
					
				}
				
			} catch (err:Error) {
				Alert.show(err.toString());
				
			}
		}
		
	
		public static function showContent(type:String):void {
			try{
			if (type == GUIController.ATL_FILE) {
				controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), Util.CONTENT);
				return;
			} else if (type == GUIController.SRC_METAMODEL) {
				
				var file:FileReference;
				var bArray:ByteArray;
				var selectedFileArray:Array = fileKeepers.browserSrcMM.fileList;
				var content:String = "";
				
				for (var i:uint = 0; i < selectedFileArray.length; i++)	{
					file = FileReference(selectedFileArray[i]);
					bArray = file.data;
					content += "File " + file.name + ":\n\n" + bArray.toString() + "\n\n ---End of File---\n\n";
					
				}
				
				//var bArray:ByteArray = fileKeepers.browserSrcMM.data;
				controller.showPopUpString(content);
				
				
			} else if (type == GUIController.TRGT_METAMODEL) {
				
				
				var bArray2:ByteArray = fileKeepers.browserTrgtMM.data;
				controller.showPopUpString(bArray2.toString());
				
			}
			
			} catch (err:Error) {
				Alert.show(err.toString());
			}
		}
		
		public static function toggleImg(state:Boolean, type:String):void {
			controller.getImage(type).enabled = state;
		}
		
		/**
		 * Goes back to the main state
		 * */
		public static function backToMain():void {
			
			controller.getAction(GUIController.UPLOAD).play(null, true);
			resetField(GUIController.ATL_FILE);
			resetField(GUIController.SRC_METAMODEL);
			resetField(GUIController.TRGT_METAMODEL);
			toggleUploadButton(false);
			toggleSelectAtlButton(true);
			controller.getImage(GUIController.ATL_FILE).setVisible(false);
			controller.getImage(GUIController.SRC_METAMODEL).setVisible(false);
			controller.getImage(GUIController.TRGT_METAMODEL).setVisible(false);
			controller.getProgressBar(GUIController.UPLOAD).x = 36;
			fileKeepers.clearData();
			controller.changeState("Main, anything");
		}
		
		
		/**
		 * Handles the request to execute the current transformation
		 * */
		public static function goToExecutionHandler(event:CloseEvent):void {
			if (event.detail == Alert.YES) {
				
				controller.getAction(GUIController.UPLOAD).play(null, true);
				
				toggleUploadButton(false);
				toggleSelectAtlButton(true);
				controller.getProgressBar(GUIController.UPLOAD).x = 36;
				
				controller.changeState(GUIController.EXECUTE);
				controller.getWebService().getAllATLTransformations(session.getId());
				fileKeepers.clearData();
				
			}
			controller.getButton(GUIController.TO_EXECUTE).mouseEnabled = true;
			controller.getButton(GUIController.TO_EXECUTE).setStyle("chromeColor", 0xe3dddd);
			controller.getButton(GUIController.TO_EXECUTE).setStyle("color", 0x000000);
			controller.getMenu().getMenuAt(1).enabled = true;
			
		}
		
		public static function toggleProgressBar(on:Boolean):void {
			controller.getProgressBar(GUIController.UPLOAD).setVisible(on);
		}
		
		public static function changeMetamodelInputText(type:String, name:String):void {
			controller.getTextInput(type).text = name + " required";
		}
		
		public static function imgMouseOver(over:Boolean, type:String):void {
			if (over)
				controller.getImage(type).source = Util.OVER_CONTENT_IMAGE_PATH;
			else
				controller.getImage(type).source = Util.CONTENT_IMAGE_PATH;
		}
		
		public static function imgClicked(down:Boolean, type:String):void {
			if (down) {
				controller.getImage(type).source = Util.CLICKED_CONTENT_IMAGE_PATH;
			} else {
				controller.getImage(type).source = Util.CONTENT_IMAGE_PATH;
				showContent(type);
			}
				
		}
		
		public static function getContentHold():ArrayList {
			return contentHold;
		}
		
	}
}